#include<bits/stdc++.h>
#define lc o<<1
#define rc o<<1|1
using namespace std;
const int MAXN=1e5+10;
int n,m,cnt,head[MAXN],pre[MAXN],coll[MAXN*4],colr[MAXN*4],sumv[MAXN*4],addv[MAXN*4];
struct edge
{
	int v,next;
}e[MAXN*2];
struct tree
{
	int num,top,fa,son,sub,sum,depth;
}a[MAXN];
void addedge(int x,int y)
{
	e[++cnt]=(edge){y,head[x]};
	head[x]=cnt;
	return;
}
void dfs1(int u,int fa,int depth)
{
	a[u].depth=depth;
	a[u].fa=fa;
	a[u].sum=1;
	int t=0;
	for(int i=head[u];i;i=e[i].next)
	{
		int v=e[i].v;
		if(v==fa)continue;
		dfs1(v,u,depth+1);
		a[u].sum+=a[v].sum;
		if(a[v].sum>t)
		{
			a[u].son=v;
			t=a[v].sum;
		}
	}
	return;
}
void dfs2(int u,int last)
{
	pre[++cnt]=u;
	a[u].sub=cnt;
	a[u].top=last;
	if(a[u].son)dfs2(a[u].son,last);
	for(int i=head[u];i;i=e[i].next)
	{
		int v=e[i].v;
		if(v==a[u].fa||v==a[u].son)continue;
		else dfs2(v,v);
	}
	return;
}
void push_up(int o)
{
	sumv[o]=sumv[lc]+sumv[rc];
	if(colr[lc]==coll[rc])--sumv[o];
	coll[o]=coll[lc];
	colr[o]=colr[rc];
	return;
}
void push_down(int o)
{
	if(addv[o])
	{
		sumv[lc]=sumv[rc]=1;
		addv[lc]=addv[rc]=coll[lc]=colr[lc]=coll[rc]=colr[rc]=addv[o];
		addv[o]=0;
	}
	return;
}
void build(int o,int l,int r)
{
	if(l==r)
	{
		coll[o]=colr[o]=a[pre[l]].num;
		sumv[o]=1;
		return;
	}
	int mid=(l+r)>>1;
	build(lc,l,mid);
	build(rc,mid+1,r);
	push_up(o);
	return;
}
void update_sum(int o,int l,int r,int yl,int yr,int v)
{
	if(yl<=l&&r<=yr)
	{
		sumv[o]=1;
		coll[o]=colr[o]=addv[o]=v;
		return;
	}
	int mid=(l+r)>>1;
	push_down(o);
	if(yl<=mid)update_sum(lc,l,mid,yl,yr,v);
	if(yr>mid)update_sum(rc,mid+1,r,yl,yr,v);
	push_up(o);
	return;
}
void update(int u,int v,int k)
{
	while(true)
	{
		int f1=a[u].top,f2=a[v].top;
		if(f1==f2)
		{
			int l=min(a[u].sub,a[v].sub),r=max(a[u].sub,a[v].sub);
			update_sum(1,1,n,l,r,k);
			break;
		}
		if(a[f1].depth>a[f2].depth)
		{
			int l=a[f1].sub,r=a[u].sub;
			update_sum(1,1,n,l,r,k);
			u=a[f1].fa;
		}
		else
		{
			int l=a[f2].sub,r=a[v].sub;
			update_sum(1,1,n,l,r,k);
			v=a[f2].fa;
		}
	}
	return;
}
int query_sum(int o,int l,int r,int yl,int yr,int &retl,int &retr)
{
	if(yl<=l&&r<=yr)
	{
		if(l==yl)retl=coll[o];
		if(r==yr)retr=colr[o];
		return sumv[o];
	}
	int mid=(l+r)>>1,ll=0,rr=0,ret=0;
	push_down(o);
	if(yl<=mid)
	{
		ret=query_sum(lc,l,mid,yl,yr,retl,retr);
		ll=colr[lc];
	}
	if(yr>mid)
	{
		ret+=query_sum(rc,mid+1,r,yl,yr,retl,retr);
		rr=coll[rc];
	}
	if(ll==rr)--ret;
	return ret;
}
int query(int u,int v)
{
	int ull=0,vll=0,ans=0;
	while(true)
	{
		int f1=a[u].top,f2=a[v].top;
		if(f1==f2)
		{
			int l=min(a[u].sub,a[v].sub),r=max(a[u].sub,a[v].sub),ll,rr;
			ans+=query_sum(1,1,n,l,r,ll,rr);
			if(a[u].depth>a[v].depth)
			{
				if(ll==vll)--ans;
				if(rr==ull)--ans;
			}
			else
			{
				if(ll==ull)--ans;
				if(rr==vll)--ans;
			}
			break;
		}
		if(a[f1].depth>a[f2].depth)
		{
			int l=a[f1].sub,r=a[u].sub,ll,rr;
			ans+=query_sum(1,1,n,l,r,ll,rr);
			if(rr==ull)--ans;
			ull=ll;
			u=a[f1].fa;
		}
		else
		{
			int l=a[f2].sub,r=a[v].sub,ll,rr;
			ans+=query_sum(1,1,n,l,r,ll,rr);
			if(rr==vll)--ans;
			vll=ll;
			v=a[f2].fa;
		}
	}
	return ans;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)
	{
		scanf("%d",&a[i].num);
		++a[i].num;
	}
	for(int i=1;i<n;++i)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		addedge(x,y);
		addedge(y,x);
	}
	dfs1(1,0,1);
	cnt=0;
	dfs2(1,1);
	build(1,1,n);
	while(m--)
	{
		char t1[3];
		int t2,t3,t4;
		scanf("%s",t1);
		scanf("%d%d",&t2,&t3);
		if(t1[0]=='Q')printf("%d\n",query(t2,t3));
		else
		{
			scanf("%d",&t4);
			update(t2,t3,t4+1);
		}
	}
	return 0;
}
